package com.suns.controller;

import com.google.code.kaptcha.Constants;
import com.suns.domain.Admin;
import com.suns.domain.User;
import com.suns.service.ApplicationService;
import com.suns.service.IncomeService;
import com.suns.util.CookieUtil;
import com.suns.service.UserService;
import com.suns.util.RedisUtil;
import com.suns.util.TokenGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Objects;

@Controller
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private ApplicationService applicationService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private IncomeService incomeService;
    @PostMapping("/login")
    @ResponseBody
    public Result login(@RequestParam String tel, @RequestParam String pwd, @RequestParam String verifyCode,
                        @RequestParam int rememberMe,
                        HttpSession session, HttpServletResponse response) throws Exception {
        String captcha = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (verifyCode.equals(captcha)) {
            User user = userService.login(tel, pwd);
            boolean flag = user != null;
            Integer code = flag ? Code.LOGIN_OK : Code.LOGIN_ERR;
            String msg = flag ? "登录成功!" : "账号或密码错误!";
            if (flag) {
                // 生成随机的 token
                String token = TokenGenerator.generateToken();
                String cookieValue = CookieUtil.encrypt(user.toString(), "cookie_key");
                redisUtil.set(token, cookieValue, 60 * 60 * 24 * 7);
                session.setAttribute("TOKEN", token);

                // 如果勾选了“记住我”选项，则将用户信息存储到cookie中
                boolean RM;
                RM = rememberMe == 1;
                if (RM) {
                    Cookie cookie1 = new Cookie("TOKEN", token);
                    cookie1.setMaxAge(60 * 60 * 24 * 7); // 设置cookie过期时间为七天
                    cookie1.setPath("/"); // 设置cookie的作用路径为整个网站
                    response.addCookie(cookie1);
                    Cookie cookie = new Cookie("rememberMe", cookieValue);
                    cookie.setMaxAge(60 * 60 * 24 * 7); // 设置cookie过期时间为1周
                    cookie.setPath("/"); // 设置cookie的作用路径为整个网站
                    response.addCookie(cookie);
                }
            }
            return new Result(code, tel, msg);
        } else {
            return new Result(0, tel, "验证码错误!");
        }
    }

    @GetMapping("/autologin")
    public String autoLogin(HttpServletRequest request, HttpSession session) throws Exception {
        String token = (String) request.getSession().getAttribute("TOKEN");
        if (token == null) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    // 如果找到了名为rememberMe的cookie，则进行自动登录
                    if ("rememberMe".equals(cookie.getName())) {
                        String cookieValue = cookie.getValue();
                        String decryptValue = CookieUtil.decrypt(cookieValue, "cookie_key");
                        User C_user = User.fromJsonString(decryptValue);
                        // 从redis缓存中获取用户信息
                        token = gettoken(request);
                        User user = null;
                        if (token != null) {
                            String json = CookieUtil.decrypt(redisUtil.get(token), "cookie_key");
                            user = User.fromJsonString(json);
                        }
                        if (user != null && C_user != null) {
                            if (Objects.equals(C_user.getTel(), C_user.getTel())) {
                                return "redirect:/users/main";
                            }
                        } else {
                            // 如果cookie的信息与redis缓存的信息不一致，则删除cookie
                            cookie.setMaxAge(0);
                            cookie.setPath("/");
                            break;
                        }
                    }
                }
            }
        } else {
            return "redirect:/users/main";
        }
        return "UserLogin";
    }

    @PostMapping("/sign")
    @ResponseBody
    public Result sign(@RequestParam String tel, @RequestParam String pwd, @RequestParam String uType,
                       @RequestParam String verifyCode, HttpSession session) {
        String captcha = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (verifyCode.equals(captcha)) {
            boolean flag = userService.sign(tel, pwd, uType);
            Integer code = flag ? Code.SIGN_OK : Code.SIGN_ERR;
            String msg = flag ? "注册成功!" : "注册失败,该账号已存在!";
            return new Result(code, tel, msg);
        } else {
            return new Result(0, tel, "验证码错误!");
        }
    }

    @GetMapping("/main")
    public String usermain(Model model, HttpServletRequest request) throws Exception {
        String token = gettoken(request);
        if (token != null) {
            String json = CookieUtil.decrypt(redisUtil.get(token), "cookie_key");
            User user = User.fromJsonString(json);
            Integer code = user != null ? Code.LOGIN_OK : Code.GET_ERR;
            String msg = user != null ? "信息获取成功!" : "信息获取失败!";
            model.addAttribute("Result", new Result(code, user, msg));
        }
        return "UserMain";
    }

    @GetMapping("/userinfo")
    public String userinfo(Model model, HttpServletRequest request) throws Exception {
        String token = gettoken(request);
        if (token != null) {
            String json = CookieUtil.decrypt(redisUtil.get(token), "cookie_key");
            User user = User.fromJsonString(json);
            Integer code = user != null ? Code.LOGIN_OK : Code.GET_ERR;
            String msg = user != null ? "信息获取成功!" : "信息获取失败!";
            model.addAttribute("Result", new Result(code, user, msg));
        }
        return "UserInfo";
    }

    @PostMapping("/UpUserInfo")
    @ResponseBody
    public Result UpUserInfo(@RequestParam String tel
            , @RequestParam String name
            , @RequestParam String pwd
            , @RequestParam(defaultValue = "null") String newpwd
            ,HttpServletRequest request,HttpServletResponse response) throws Exception {
        newpwd = Objects.equals(newpwd, "null") ? null : newpwd;
        boolean flag = userService.updateUser(tel, name, pwd, newpwd);
        if(flag){
//                修改成功后更新redis 和cookie
            String token=gettoken(request);
            if(token!=null){
                redisUtil.del(token);
            }
            String p=newpwd!=null?newpwd:pwd;
            User user = userService.userlogin(tel,p);
            //更新redis
            String cookieValue = CookieUtil.encrypt(user.toString(), "cookie_key");
            redisUtil.set(token, cookieValue, 60 * 60 * 24 * 7);
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    // 找到了名为rememberMe的cookie,则更新Cookie
                    if ("rememberMe".equals(cookie.getName())) {
                        Cookie cookie1=new Cookie("TOKEN",token);
                        cookie1.setMaxAge(60 * 60 * 24 * 7); // 设置cookie过期时间为七天
                        cookie1.setPath("/"); // 设置cookie的作用路径为整个网站
                        response.addCookie(cookie1);
                        cookie = new Cookie("rememberMe", cookieValue);
                        cookie.setMaxAge(60 * 60 * 24 * 7);
                        cookie.setPath("/");
                        response.addCookie(cookie);
                    }
                }
            }
        }
        Integer code=flag ? Code.UPDATE_OK : Code.UPDATE_ERR;
        String msg=flag ? "信息修改成功!":"密码错误,请重试!";
        return new Result(code,tel,msg);
}

    @GetMapping("/usercheckcount")
    public String usercheckcount(Model model,HttpServletRequest request) throws Exception {
        String token=gettoken(request);
        if(token!=null){
            String json =CookieUtil.decrypt(redisUtil.get(token),"A_cookie_key");
            User user=User.fromJsonString(json);
            Integer code= user!=null ? Code.LOGIN_OK : Code.GET_ERR;
            String msg= user!=null ? "信息获取成功!" : "信息获取失败!";
            model.addAttribute("Result", new Result(code,user,msg));
        }
        return "UserCheckCount";
    }


    @GetMapping("/logout")
    public String logout(Model model,HttpServletResponse response,HttpServletRequest request){
        String token=gettoken(request);
        String admin=null;
        if(token!=null){
            redisUtil.del(token);
            Cookie cookie = new Cookie("rememberMe", null);
            cookie.setMaxAge(0);
            cookie.setPath("/");
            response.addCookie(cookie);
            Cookie cookie1 = new Cookie("TOKEN", null);
            cookie1.setMaxAge(0);
            cookie1.setPath("/");
            response.addCookie(cookie1);
            admin=redisUtil.get(token);
            HttpSession session = request.getSession(false);
            if(session != null){
                session.removeAttribute("TOKEN");
            }
        }
        Integer code= admin==null ? Code.LOGOUT_OK : Code.LOGOUT_ERR;
        String msg= admin==null ? "退出成功!" : "网络异常,请稍后重试!";
        model.addAttribute("Result", new Result(code,null,msg));
        return "UserLogin";
    }
    @GetMapping("/useraddlicenseplate")
    public String useraddlicenseplate(Model model,HttpServletRequest request) throws Exception {
        String token=gettoken(request);
        if(token!=null){
            String json =CookieUtil.decrypt(redisUtil.get(token),"A_cookie_key");
            User user=User.fromJsonString(json);
            Integer code= user!=null ? Code.LOGIN_OK : Code.GET_ERR;
            String msg= user!=null ? "信息获取成功!" : "信息获取失败!";
            model.addAttribute("Result", new Result(code,user,msg));
        }
        return "UserAddLicensePlate";
    }
//添加车牌号
    @PostMapping("/UserAddLicense")
    @ResponseBody
    public Result userAddLicense(@RequestParam String tel,@RequestParam String carnumber,@RequestParam String carnumber1,@RequestParam String carnumber2,@RequestParam String carnumber3,HttpServletRequest request,HttpServletResponse response) throws Exception {
           boolean flag;
            if(carnumber.equals(carnumber1)||carnumber.equals(carnumber2)||carnumber.equals(carnumber3)){
                Integer code= Code.SAVE_ERR;
                String msg= "车牌号已经存在，添加失败!";
                return new Result(code,tel,msg);
            }
         else {
             flag=userService.addlicense(tel,carnumber,carnumber1,carnumber2,carnumber3);
             //更新Cookie和Redis
                NewCookie(tel, request, response, flag);
                Integer code=flag ? Code.SAVE_OK : Code.SAVE_ERR;
            String msg=flag ? "车牌号添加成功!" : "车牌号已经存在，添加失败!";
            return new Result(code,tel,msg);}

    }
    @GetMapping("/usermodifylicense")
    public String usermodifylicense(Model model,HttpServletRequest request) throws Exception {
        String token = gettoken(request);
        if (token != null) {
            String json = CookieUtil.decrypt(redisUtil.get(token), "A_cookie_key");
            User user = User.fromJsonString(json);
            Integer code = user != null ? Code.LOGIN_OK : Code.GET_ERR;
            String msg = user != null ? "信息获取成功!" : "信息获取失败!";
            model.addAttribute("Result", new Result(code, user, msg));
        }
        return "UserModifyLicense";
    }
    //修改车牌号
    @PostMapping("/ModifyLicense")
    @ResponseBody
    public Result modifylicense(@RequestParam String tel,@RequestParam String ocarnumber1,@RequestParam String ocarnumber2,@RequestParam String ocarnumber3,@RequestParam String carnumber1,@RequestParam String carnumber2,@RequestParam String carnumber3,HttpServletResponse response,HttpServletRequest request) throws Exception {
        boolean flag=userService.modifylicense(tel,ocarnumber1,ocarnumber2,ocarnumber3,carnumber1,carnumber2,carnumber3);
        NewCookie(tel, request, response, flag);
        Integer code=flag ? Code.UPDATE_OK : Code.UPDATE_ERR;
        String msg=flag ? "车牌号修改成功!" : "车牌号修改失败!";
        return new Result(code,tel,msg);
    }
    //删除车牌号
    @PostMapping("/DeleteLicense")
    @ResponseBody
    public Result deletelicense(@RequestParam String tel,@RequestParam String order1,@RequestParam String order2,@RequestParam String order3,HttpServletRequest request,HttpServletResponse response) throws Exception {
        boolean flag=userService.deletelicense(tel,order1,order2,order3);
        //更新Cookie和Redis
        NewCookie(tel, request, response, flag);
        Integer code=flag ? Code.UPDATE_OK : Code.UPDATE_ERR;
        String msg=flag ? "车牌号删除成功!" : "车牌号删除失败!";
        return new Result(code,tel,msg);
    }

    private void NewCookie(@RequestParam String tel, HttpServletRequest request, HttpServletResponse response, boolean flag) throws Exception {
        if(flag) {
//                修改成功后更新redis 和cookie
            String token = gettoken(request);
            if (token != null) {
                redisUtil.del(token);
            }
            User user = userService.getBytel(tel);
            if (user!=null){
                //更新redis
                String cookieValue = CookieUtil.encrypt(user.toString(), "cookie_key");
                redisUtil.set(token, cookieValue, 60 * 60 * 24 * 7);
                Cookie[] cookies = request.getCookies();
                if (cookies != null) {
                    for (Cookie cookie : cookies) {
                        // 找到了名为rememberMe的cookie,则更新Cookie
                        if ("rememberMe".equals(cookie.getName())) {
                            Cookie cookie1 = new Cookie("TOKEN", token);
                            cookie1.setMaxAge(60 * 60 * 24 * 7); // 设置cookie过期时间为七天
                            cookie1.setPath("/"); // 设置cookie的作用路径为整个网站
                            response.addCookie(cookie1);
                            cookie = new Cookie("rememberMe", cookieValue);
                            cookie.setMaxAge(60 * 60 * 24 * 7);
                            cookie.setPath("/");
                            response.addCookie(cookie);
                        }
                    }
                }
            }
        }
    }

    @GetMapping("/userrecharge")
public String userrecharge(Model model,HttpServletRequest request) throws Exception {
    String token = gettoken(request);
    if (token != null) {
        String json = CookieUtil.decrypt(redisUtil.get(token), "cookie_key");
        User user = User.fromJsonString(json);
        Integer code = user != null ? Code.GET_OK : Code.GET_ERR;
        String msg = user != null ? "信息获取成功!" : "信息获取失败!";
        model.addAttribute("Result", new Result(code, user, msg));
    }
    return "UserRecharge";
}
//充值
    @PostMapping("/Recharge")
    @ResponseBody
    public Result Recharge(@RequestParam String tel, @RequestParam BigDecimal oldmoney, @RequestParam BigDecimal remoney,HttpServletRequest request,HttpServletResponse response) throws Exception {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowStr = formatter.format(now);
        User user=userService.getBytel(tel);
        boolean flag=false;
        if (user!=null){
            flag=incomeService.addIncome(user.getTel(),user.getName(),user.getUsertype(),nowStr,oldmoney,remoney);
        }
        NewCookie(tel,request,response,flag);
        Integer code=flag ? Code.UPDATE_OK : Code.UPDATE_ERR;
        String msg=flag ? "充值成功!" : "充值失败!";
        return new Result(code,tel,msg);
    }
//退费
    @GetMapping("/userreturn")
    public String userreturn(Model model,HttpServletRequest request) throws Exception {
        String token = gettoken(request);
        if (token != null) {
            String json = CookieUtil.decrypt(redisUtil.get(token), "A_cookie_key");
            User user = User.fromJsonString(json);
            String flag = null;
            if(user!=null){
               flag=applicationService.getUserDel(user.getTel());
            }
            Integer code = null;
            String msg = null;
            if(Objects.equals(flag, "未提交申请")){
                code=Code.SH_FINISH;
            }else if (Objects.equals(flag, "待审批")){
               code= Code.SH_ING;
               msg="申请审核中,请耐心等待!(管理员未审批时,无法提交下一次申请!)";
            }else if (flag!=null){
                code=Code.SH_FINISH;
                msg="上一次的申请已审批,审批结果为:"+flag;
            }
            model.addAttribute("Result", new Result(code, user, msg));
        }
        return "UserReturn";
    }
    @PostMapping("/Return")
    @ResponseBody
public Result Return(@RequestParam String tel, @RequestParam BigDecimal remoney,@RequestParam String pwd) throws Exception {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowStr = formatter.format(now);
        User user=userService.login(tel,pwd);
        boolean flag=false;
        if(user!=null){
            flag=applicationService.userreturn(user.getName(),tel,remoney,nowStr,user.getUsertype());
        }
        Integer code=flag ? Code.SAVE_OK : Code.SAVE_ERR;
        String msg=flag ? "退费申请提交成功" : "密码错误!";
        return new Result(code,tel,msg);
 }

    public static String gettoken(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        String token = (String)request.getSession().getAttribute("TOKEN");
        if(token==null){
            for (Cookie cookie1 : cookies) {
                if("TOKEN".equals(cookie1.getName())){
                    token = cookie1.getValue();
                }
            }
        }
        return token;
    }
}


